#include <pthread.h>
#include <unistd.h>
#include "Wrappers/Pthread/Mutex.hpp"
#include "Wrappers/Pthread/MutexScopedLock.hpp"
#include "Wrappers/Pthread/Tests/Mutex_tests.hpp"

namespace wrappers {
namespace pthread {

Mutex_tests::Mutex_tests()
    : mTestRunner("Mutexes's tests")
{
  mTestRunner.AddTestCase(UTESTS_MAKE_CASE_DATA(Mutex_tests::MainTest));
  mTestRunner.Run(true);
}

Mutex_tests::~Mutex_tests()
{

}

UTESTS_START_TEST(Mutex_tests::MainTest)
{
  Mutex mutex;
  pthread_t thread;

  pthread_create(&thread, NULL, Mutex_tests::ThreadTimedLocker, &mutex);
  usleep(500);
  UTESTS_FAIL_IF(mutex.TryLock() == true,
      "Parent: Lock acquired - should have failed");
  usleep(2000);
  UTESTS_FAIL_IF(mutex.TryLock() == false,
      "Parent: Lock cannot be acquired");
}
UTESTS_END_TEST

void *Mutex_tests::ThreadTimedLocker(void *args)
{
  Mutex *mutex = (Mutex *) args;

  MutexScopedLock scopedMutex(*mutex);
  usleep(1000);
  return NULL;
}

} /* namespace pthread */
} /* namespace wrappers */
